{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用梯度上升法实现PCA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = np.empty((100, 2))\n",
    "X[:,0] = np.random.uniform(0., 100., size=100)\n",
    "X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x109eaacf8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:,0], X[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### demean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def demean(X):\n",
    "    return X - np.mean(X, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X_demean = demean(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nzP8D4uUMPhawvc4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10d2c5b00>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0], X_demean[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.3500311979441904e-15"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X_demean[:,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-7.6738615462090825e-15"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(X_demean[:,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 梯度上升法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def f(w, X):\n",
    "    return np.sum((X.dot(w)**2)) / len(X)\n",
    "\n",
    "def df_math(w, X):\n",
    "    return X.T.dot(X.dot(w)) * 2. / len(X)\n",
    "\n",
    "def df_debug(w, X, epsilon=0.0001):\n",
    "    res = np.empty(len(w))\n",
    "    for i in range(len(w)):\n",
    "        w_1 = w.copy()\n",
    "        w_1[i] += epsilon\n",
    "        w_2 = w.copy()\n",
    "        w_2[i] -= epsilon\n",
    "        res[i] = (f(w_1, X) - f(w_2, X)) / (2 * epsilon)\n",
    "    return res\n",
    "\n",
    "def direction(w):\n",
    "    return w / np.linalg.norm(w)\n",
    "\n",
    "def gradient_ascent(df, X, initial_w, eta, n_iters = 1e4, epsilon=1e-8):\n",
    "    \n",
    "    w = direction(initial_w) \n",
    "    cur_iter = 0\n",
    "\n",
    "    while cur_iter < n_iters:\n",
    "        gradient = df(w, X)\n",
    "        last_w = w\n",
    "        w = w + eta * gradient\n",
    "        w = direction(w) # 注意1：每次求一个单位方向\n",
    "        if(abs(f(w, X) - f(last_w, X)) < epsilon):\n",
    "            break\n",
    "            \n",
    "        cur_iter += 1\n",
    "\n",
    "    return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.37061708,  0.28515471])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initial_w = np.random.random(X.shape[1]) # 注意2：不能用0向量开始\n",
    "initial_w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "eta = 0.001\n",
    "# 注意3： 不能使用StandardScaler标准化数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.78121351,  0.62426392])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient_ascent(df_debug, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.78121351,  0.62426392])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gradient_ascent(df_math, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "w = gradient_ascent(df_math, X_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nqTocrAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10d32b860>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_demean[:,0], X_demean[:,1])\n",
    "plt.plot([0, w[0]*30], [0, w[1]*30], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用极端数据集测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X2 = np.empty((100, 2))\n",
    "X2[:,0] = np.random.uniform(0., 100., size=100)\n",
    "X2[:,1] = 0.75 * X2[:,0] + 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10d45b780>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2[:,0], X2[:,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X2_demean = demean(X2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "w2 = gradient_ascent(df_math, X2_demean, initial_w, eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nrkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10d589cc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X2_demean[:,0], X2_demean[:,1])\n",
    "plt.plot([0, w2[0]*30], [0, w2[1]*30], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同学们可以自己思考实现随机梯度下降法和小批量梯度下降法的版本：）"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
